// 单例模式配置类实现
#ifndef __MY_CONFIG__
#define __MY_CONFIG__
#include "util.hpp"
#include <mutex>

// 采用宏定义配置文件
#define CONFIG_FILE "./cloud.conf"
namespace cloud
{
    class Config
    {
    private:
        // 配置信息中管理的数据
        int _hot_time;                // 热点时间
        std::string _server_ip;       // 服务器ip地址
        int _server_port;             // 服务器端口号
        std::string _download_prefix; // 下载的前缀名
        std::string _packfile_suffix; // 压缩包的后缀名称
        std::string _pack_dir;        // 压缩包存放目录
        std::string _back_dir;        // 备份文件存放目录
        std::string _backup_file;     // 全部已备份文件，方便查看已备份文件
    private:
        // 单例模式-构造函数私有化
        Config()
        {
            // 在构造函数中对各个成员变量进行赋值，将配置信息数据放入对应位置
            ReadConfigFile();
        }
        // 在类内实例化静态成员指针
        static Config *_instance;
        // 定义一个互斥锁-读的时候不加锁，写的时候加锁
        static std::mutex _mutex;

    private:
        // 提供一个接口读取配置文件，将配置文件中的数据放到对应的成员变量中
        bool ReadConfigFile()
        {
            // 采用文件工具类
            cloud::FileUtil fu(CONFIG_FILE);
            // 获取文件中的全部数据
            std::string body;
            if (fu.GetContent(&body) == false)
            {
                std::cout << "load config file failed!\n";
                return false;
            }
            // 进行反序列化，将字符串中的内容放到Json::Value中
            Json::Value root;
            if (cloud::JsonUtil::UnSerialize(body, &root) == false)
            {
                std::cout << "parse config file failed!\n";
                return false;
            }
            // 把配置文件中的信息读出来
            _hot_time = root["hot_time"].asInt();                  // 热点时间
            _server_port = root["server_port"].asInt();            // 服务器端口信息
            _server_ip = root["server_ip"].asString();             // 服务器ip
            _backup_file = root["backup_file"].asString();         // 全部已备份信息
            _back_dir = root["back_dir"].asString();               // 热点文件存放路径
            _pack_dir = root["pack_dir"].asString();               // 非热点文件存放路径
            _download_prefix = root["download_prefix"].asString(); // 下载的前缀
            _packfile_suffix = root["packfile_suffix"].asString(); // 压缩包的后缀名称
            return true;
        }

    public:
        static Config *GetInstance()
        {
            // 二次检测，如果为空再次进行检测
            if (_instance == nullptr)
            {
                _mutex.lock();
                if (_instance == nullptr)
                {
                    _instance = new Config;
                }
                // 创建完成之后进行解锁
                _mutex.unlock();
            }
            return _instance;
        }
        // 提供统一的接口获取配置文件中的信息
        //  获取热点时间
        int GetHotTime()
        {
            return _hot_time;
        }
        // 获取服务端端口
        int GetServerPort()
        {
            return _server_port;
        }
        // 获取服务端ip地址
        std::string GetServerIp()
        {
            return _server_ip;
        }
        // 获取文件下载前缀
        std::string GetDownloadPrefix()
        {
            return _download_prefix;
        }
        // 获取压缩包后缀
        std::string GetPackfileSuffix()
        {
            return _packfile_suffix;
        }
        // 获取非热点文件存放目录
        std::string GetPackDir()
        {
            return _pack_dir;
        }
        // 获取热点文件存放目录
        std::string GetBackDir()
        {
            return _back_dir;
        }
        // 获取存放全部已备份文件的路径名
        std::string GetBackUpFile()
        {
            return _backup_file;
        }
    };
    // 静态成员在类外进行定义
    Config *Config::_instance = nullptr; // nullptr和NULL的区别
    std::mutex Config::_mutex;
}
#endif